<template>
  <div>
    <q-table
      :grid="$q.screen.xs"
      :rows="data"
      :columns="columns"
      row-key="id"
      :rows-per-page-options="[0]"
      v-model:pagination="pagination"
      binary-state-sort
      separator="cell"
      selection="multiple"
      v-model:selected="selected"
      :style="$q.screen.xs ? '' : 'max-height: calc(100vh - 100px)'"
      class="my-sticky-virtscroll-table"
    >
      <template v-slot:top>
        <div class="text-redtext-bold">
          <ol>
            <li>删除不需要导入的数据行</li>
            <li>需要导入的数据列不要留空白，若有空白数据，请调整excel文件后重新导入</li>
            <li>请正确配置<span class="text-primary text-bold">系统字段与excel列</span>的对应关系</li>
            <li>
              <div class="flex items-center">
                <span>可以为多个excel列配置同一个系统字段，后续会把多列数据合并成指定的系统字段，合并时使用的连接符</span>
                <q-input dense filled v-model="concatChar" style="width: 40px" />
              </div>
            </li>
            <slot name="tips"></slot>
          </ol>
        </div>
        <q-space />
        <q-btn class="self-end" color="red" label="删除选中行" :disable="selected.length < 1" @click="deleteRow" />
      </template>

      <template v-slot:header="props">
        <q-tr :props="props">
          <q-th class="bg-orange-4">系统字段</q-th>
          <q-th
            class="bg-orange-4"
            v-for="col in props.cols"
            :key="col.name"
            :props="props"
          >
            <q-select borderless dense v-model="mappingColumn[col.name]" :options="options" v-if="col.name != 'id'" clearable />
          </q-th>
        </q-tr>
        <q-tr :props="props">
          <q-th class="bg-grey-3">excel字段</q-th>
          <q-th
            class="bg-grey-3"
            v-for="col in props.cols"
            :key="col.name"
            :props="props"
          >
            {{ col.label }}
          </q-th>
        </q-tr>
      </template>

      <template v-slot:body="props">
        <q-tr :props="props">
          <q-td auto-width>
            <q-checkbox v-model="props.selected" />
          </q-td>
          <q-td :key="col.name" :props="props" v-for="col in props.cols">
            <div>
              {{ col.value }}
            </div>
            <div class="text-red" v-if="mappingColumn[col.name] && mappingColumn[col.name].required && !col.value">
              <q-icon name="error" />不能为空
            </div>
          </q-td>
        </q-tr>
      </template>
    </q-table>
  </div>
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'previewData',
  props: {
    uid: String
  },
  data () {
    return {
      data: [],
      columns: [],
      selected: [],
      pagination: {
        sortBy: 'id',
        descending: false,
        page: 1,
        rowsPerPage: 0
        // rowsNumber: 10
      },
      options: [],
      mappingColumn: {},
      concatChar: '*'
    }
  },
  mounted () {
    this.$storage.get(`concatChar_${this.uid}`, true).then(param => {
      if (param) {
        this.concatChar = param;
      }
    });
  },
  methods: {
    /**
     * 预览数据
     * @param {array} columns excel里的字段定义
     * @param {array} data excel里的数据
     * @param {array} fields 系统字段 [{ value: '系统字段名', label: '字段中文名', required: true/false, column: 'excel列定义里的字段' }]
     */
    previewData ({ columns, data, fields }) {
      this.columns = columns;
      this.data = data;
      this.options = fields;

      this.mappingColumn = {};
      columns.forEach(col => { this.mappingColumn[col.name] = null });

      this.$storage.get(`previewDataConfig_${this.uid}`, true).then(param => {
        if (this.uid && param) {
          this.mappingColumn = param;
          // excel变动，可能存在不存在的列
          for (const key in this.mappingColumn) {
            if (columns.filter(col => col.field == key).length === 0) {
              delete this.mappingColumn[key];
            }
          }
        // console.log(this.mappingColumn);
        } else {
          for (const opt of fields) {
            if (opt.column) {
              this.mappingColumn[opt.column] = opt;
            }
          }
        }
      });
    },
    // 验验并输出数据
    validateData () {
      const colName = key => { // 取数据列定义
        const item = this.columns.filter(v => v.name == key);
        if (item.length > 0) {
          return item[0];
        } else {
          return {};
        }
      };
      const optDefine = key => {
        const colVal = this.mappingColumn[key];
        if (colVal) {
          let value = colVal;
          if (typeof colVal === 'object') {
            value = colVal.value;
          }

          return this.options.filter(v => v.value == value)[0]
        } else {
          return {};
        }
      }

      const message = []; // 错误消息列表

      for (const row of this.data) {
        const col = [];
        for (const key in this.mappingColumn) {
          if (key && this.mappingColumn[key]) {
            const opt = optDefine(key);
            if (row[key] === '' && opt.required) {
              col.push(colName(key).label);
            }
          }
        }
        if (col.length > 0) {
          message.push({
            id: row.id,
            error: `${col.join(',')} 不能为空`
          });
        }
      }

      if (message.length > 0) {
        return {
          result: 'fail',
          message
        }
      } else {
        const mapping = {};
        for (const key in this.mappingColumn) {
          if (key && this.mappingColumn[key]) {
            let field = this.mappingColumn[key];
            if (typeof field === 'object') field = field.value;
            mapping[key] = field;
          }
        }
        // 组织数据
        const formData = [];
        for (const row of this.data) {
          const formRow = { id: row.id };
          for (const key in mapping) {
            if (formRow[mapping[key]]) formRow[mapping[key]] += this.concatChar + String(row[key] || '').trim();
            else formRow[mapping[key]] = String(row[key] || '').trim();
          }
          formData.push(formRow);
        }

        return {
          result: 'ok',
          data: formData
        }
      }
    },
    deleteRow () { // 删除数据行
      if (this.selected.length > 0) {
        this.selected.forEach(row => {
          const { id } = row;
          this.data = this.data.filter(v => v.id != id);
        });
        this.selected = [];
      }
    }
  },
  watch: {
    mappingColumn: {
      handler (val) {
        if (this.uid && !Object.entries(val).every(([k, v]) => v === null)) {
          this.$storage.set(`previewDataConfig_${this.uid}`, val, true);
        }
      },
      deep: true
    },
    concatChar () {
      this.$storage.set(`concatChar_${this.uid}`, this.concatChar, true);
    }
  }
});
</script>
